
<template>
  <div class="chat_main">
    <div class="chat_left">
      <McHeader :title="'华夏金租AI知识库'" :logoImg="'/src/assets/logo.png'"></McHeader>
      <div class="chat_list">
        <div class="chat_list_title">历史对话</div>
        <McList :data="options" @select="onSelect"></McList>
      </div>
    </div>
    <div class="chat_right">
      <McLayout class="container">
        <McLayoutContent
          v-if="startPage"
          style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px"
        >
          <McIntroduction
            :logoImg="'/src/assets/logo.png'"
            :title="'华夏金租AI知识库'"
            :subTitle="'Hi，欢迎使用 华夏金租AI知识库'"
            :description="description"
          ></McIntroduction>
          <McPrompt
            :list="introPrompt.list"
            :direction="introPrompt.direction"
            class="intro-prompt"
            @itemClick="onSubmit($event.label)"
          ></McPrompt>
        </McLayoutContent>
        <McLayoutContent class="content-container" v-else>
          <template v-for="(msg, idx) in messages" :key="idx">
            <McBubble
              v-if="msg.from === 'user'"
              :content="msg.content"
              :align="'right'"
              :avatarConfig="{ imgSrc: 'https://matechat.gitcode.com/png/demo/userAvatar.svg' }"
            >
            </McBubble>
            <McBubble v-else :loading="msg.loading" :avatarConfig="{ imgSrc: 'https://matechat.gitcode.com/logo.svg' }"> 
              <template #default>
                <div v-html="mdt.render(msg.content)"></div>
              </template>
              <template #bottom>
                <div class="bubble-bottom-area">
                  <a-space>
                    <a-tooltip placement="topLeft" title="复制" arrow-point-at-center>
                      <copy-outlined />
                    </a-tooltip>
                    <a-tooltip placement="topLeft" title="重新生成" arrow-point-at-center>
                      <sync-outlined />
                    </a-tooltip>
                  </a-space>
                </div>
              </template>
            </McBubble>
          </template>
        </McLayoutContent>
        <div class="shortcut" style="display: flex; align-items: center; gap: 8px">
          <div class="add_btn_box">
            <a-tooltip title="新建对话">
              <a-button shape="circle" size="md" @click="newConversation" :icon="h(PlusOutlined)" />
            </a-tooltip>
          </div>
        </div>
        <McLayoutSender>
          <McInput :value="inputValue" :maxLength="2000" @change="(e='') => (inputValue = e)" @submit="onSubmit">
            <template #extra>
              <div class="input-foot-wrapper">
                <div class="input-foot-left">
                  <span class="input-foot-maxlength">{{ inputValue.length }}/2000</span>
                </div>
                <div class="input-foot-right">
                  <a-button :disabled="!inputValue" shape="round" @click="inputValue = ''">清空输入</a-button>
                </div>
              </div>
            </template>
          </McInput>
        </McLayoutSender>
      </McLayout>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, h } from 'vue';
import { message } from 'ant-design-vue';
import markdownit from 'markdown-it';
import hljs from 'highlight.js';
import { CopyOutlined, SyncOutlined, PlusOutlined } from '@ant-design/icons-vue';
const mdt = markdownit({ breaks: true, linkify: true, html: true }); 
mdt.set({
  highlight: function (str='', lang='') {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return '<pre class="hljs"><code>' +
          hljs.highlight(lang, str, true).value +
         '</code></pre>';
      } catch (__) {}
    }
    return '<pre class="hljs"><code>' + mdt.utils.escapeHtml(str) + '</code></pre>';
  }
});
const options = ref(
  [
    { label: `如何快速实现排序, 请使用js  实现一个快速排序`, value: 1, isabled: false, active: true},
    { label: `什么是执行流水线列表`, value: 2, isabled: false, active: false},
    { label: `如何绑定云空间中的项目`, value: 3, isabled: false, active: false},
    { label: `如何绑定云空间中的项目`, value: 4, isabled: false, active: false},
    { label: `如何绑定云空间中的项目`, value: 5, isabled: false, active: false},
    { label: `如何绑定云空间中的项目`, value: 6, isabled: false, active: false},

  ]
);
const startPage = ref(true);
const description = [
  '你好，我是华夏金租智能问答助手。',
  '作为AI模型，我提供的答案可能不总是确定或准确的，但您的反馈可以帮助我做的更好哦。',
];
const onSelect = (e = {}) => {
  console.log('list selected', e);
};
const introPrompt = {
  direction: 'horizontal',
  list: [
    {
      value: 'quickSort',
      label: '帮我写一个快速排序',
      iconConfig: { name: 'icon-info-o', color: '#5e7ce0' },
      desc: '使用 js 实现一个快速排序',
    },
    {
      value: 'helpMd',
      label: '你可以帮我做些什么？',
      iconConfig: { name: 'icon-star', color: 'rgb(255, 215, 0)' },
      desc: '了解当前大模型可以帮你做的事',
    },
    {
      value: 'bindProjectSpace',
      label: '怎么绑定项目空间',
      iconConfig: { name: 'icon-priority', color: '#3ac295' },
      desc: '如何绑定云空间中的项目',
    },
  ],
};
const newConversation = () => {
  startPage.value = true;
  messages.value = [];
}
const inputValue = ref('');
const messages = ref<any[]>([]);
import OpenAI from 'openai';
const openai = new OpenAI({
  apiKey: 'sk-1083e8a847704d1db7a56ddc7065055c', // 模型APIKey
  baseURL: 'https://api.deepseek.com', // 模型API地址
  dangerouslyAllowBrowser: true, // 浏览器环境使用需要开启
});

const onSubmit = (evt="") => {
  if(evt=="") {
    return 
  } else {
    inputValue.value='';
    startPage.value = false;
    // 用户发送消息
    messages.value.push({
      from: 'user',
      content: evt,
      avatarConfig: { name: 'user' },
    });
  fetchData(evt);
  }
};
const fetchData = async (ques = "") => {
  messages.value.push({
    from: 'model',
    content: '',
    avatarConfig: { name: 'model' },
    id: '',
    loading: true,
  });
  const completion = await openai.chat.completions.create({
    model: 'deepseek-reasoner', // 根据deepseek模型列表进行替换
    messages: [{ role: 'user', content: ques }],
    stream: true, // 为 true 则开启接口的流式返回
  });
  for await (const chunk of completion) {
    if(messages.value[messages.value.length - 1].loading) {
      messages.value[messages.value.length - 1].loading = false;
    }
    const content = chunk.choices[0]?.delta?.content || '';
    const chatId = chunk.id;
    messages.value[messages.value.length - 1].content += content;
    messages.value[messages.value.length - 1].id = chatId;
  }
  console.log(messages.value[messages.value.length - 1])
  
};
</script>

<style lang="scss">
.chat_main {
  // padding: 30px;
  display: flex;
  .chat_left{
    width: 320px;
    padding: 30px 20px;
    min-height: calc(100vh - 60px);
    background: #f9fbff;
    .mc-header-logo {
      width: 32px;
      height: 32px;
    }
    .chat_list{
      margin-top: 30px;
    }
    .chat_list_title {
      text-align: left;
      font-size: 14px;
      font-weight: 700;
      color: #252b3a;
      margin-bottom: 10px;
    }
    .mc-list .mc-list-item {
      text-align: left;
    }
  }
  .chat_right {
    width: calc(100% - 360px);
  }
  .container {
    width: 1000px;
    margin: 20px auto;
    height: calc(100vh - 130px);
    padding: 20px;
    gap: 8px;
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 16px; 
  }

  .content-container {
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow: auto;
  }
}
.input-foot-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 100%;
  margin-right: 8px;

  .input-foot-left {
    display: flex;
    align-items: center;
    gap: 8px;
    .input-foot-maxlength {
      font-size: 14px;
      color: #71757f;
    }
  }

  .input-foot-right {
    & > *:not(:first-child) {
      margin-left: 8px;
    }
  }
}
.bubble-bottom-area {
  color: #666;
  .ant-space {
    cursor: pointer;
  }
}
.add_btn_box {
  display: flex;
  justify-content: flex-end;
  width: 100%;
  padding-right: 10px;
  color: #666;
}
</style>